//
//  TurntableView.swift
//  RotationViewDemo
//
//  Created by 冉彬 on 2023/7/17.
//

import UIKit


class TurntableView: UIView {
    
    /// 显示的item数量（半圈）
    var itemCount: Int = 6 {
        didSet {
            refreshScrollViewContentSize()
        }
    }
    
    /// 自定义Item回调
    var customItemViewAction: ((TurntableView, Int) -> TurntableItem)?
    
    /// 转盘半径(转盘圆心到item锚点的长度)
    var radius: CGFloat = 0
    
    /// 转盘item总数
    var toastCount: Int = 100 {
        didSet {
            refreshScrollViewContentSize()
        }
    }
    
    
    private var itemPools: [String:[TurntableItem]] = [:]
    private var currentItems:[Int: TurntableItem] = [:]
    
    lazy var scrollerView: UIScrollView = {
        let scrollerView = UIScrollView(frame: self.bounds)
        scrollerView.showsVerticalScrollIndicator = false
        scrollerView.delegate = self
        scrollerView.contentSize = CGSize(width: 0, height: self.bounds.height/CGFloat(itemCount)*CGFloat(toastCount))
        return scrollerView
    }()
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = .white
        addSubview(scrollerView)
        self.radius = min(frame.height, frame.width) - 100
        refreshItemUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    /// 获取复用item
    /// - Parameter identifier: 识别符
    func dequeueReusableItem(identifier: String) -> TurntableItem? {
        if let items =  itemPools[identifier], items.count > 0 {
            itemPools[identifier] = Array(items.dropFirst())
            return items[0]
        }
        return nil
    }
    
    /// 加载
    func reloadUI() {
        currentItems.forEach { (key: Int, value: TurntableItem) in
            value.removeFromSuperview()
        }
        currentItems = [:]
        refreshItemUI()
    }
    
    
    
    /// 更新scrollerView的滑动范围
    private func refreshScrollViewContentSize(){
        scrollerView.contentSize = CGSize(width: 0, height: self.bounds.height/CGFloat(itemCount)*CGFloat(toastCount))
        if scrollerView.contentOffset.y > scrollerView.contentSize.height - scrollerView.bounds.height {
            scrollerView.contentOffset = CGPoint(x: 0, y: scrollerView.contentSize.height - scrollerView.bounds.height)
        }
        
    }
    
    /// 更新每个item的UI
    private func refreshItemUI() {
        let offsetY = scrollerView.contentOffset.y
        let laps = offsetY/scrollerView.bounds.height/2
        // 两个item之间夹脚
        let itemAngle = 360 / CGFloat(itemCount*2)
        (0 ..< self.toastCount).forEach { i in
            let angle: CGFloat = itemAngle * CGFloat(i) - laps*360
            if angle > -15 && angle < 195 {
                if currentItems[i] == nil {
                    let item = customItemViewAction?(self, i)
                    let defItem = TurntableItem(identifier: "TurntableItem", size: CGSize(width: 10, height: 10))
                    defItem.backgroundColor = .lightGray
                    // 添加到scrollerView上，避免scroller拦截了item上面的点击事件
                    scrollerView.addSubview(item ?? defItem)
                    currentItems[i] = item ?? defItem
                }
                let item = currentItems[i] ?? TurntableItem()
                let sides = calculateSides(angle: angle, hypotenuse: radius)
                let opposite = sides.opposite
                let adjacent = sides.adjacent
                item.refreshPoint(CGPoint(x: self.bounds.width - opposite, y: self.bounds.height/2 - adjacent + offsetY))
                // 设置透明度(渐变效果)
                var alpha: Double = 1
                if angle > -15 && angle < 15 {
                    alpha = (angle+15)/30
                }
                if angle > 165 && angle < 195 {
                    alpha = (195-angle)/30
                }
                item.alpha = alpha
            } else {
                if let item = currentItems[i] {
                    
                    if let items = itemPools[item.identifier] {
                        itemPools[item.identifier] = items + [item]
                    } else {
                        itemPools[item.identifier] = [item]
                    }
                    
                    item.removeFromSuperview()
                    currentItems[i] = nil
                    
                }
            }
            
        }
        
    }
    
    /// 计算边长
    /// - Parameters:
    ///   - angle: 角度
    ///   - hypotenuse: 斜边长
    /// - Returns: (对边，邻边)
    private func calculateSides(angle: Double, hypotenuse: Double) -> (opposite: Double, adjacent: Double) {
        let radians = angle * Double.pi / 180.0
        let opposite = hypotenuse * sin(radians)
        let adjacent = hypotenuse * cos(radians)
        return (opposite, adjacent)
    }
    
    
}

extension TurntableView: UIScrollViewDelegate {
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        refreshItemUI()
    }
    
    
    
}
